using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Game;
using Lean.Touch;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class InteractStateOperational : InteractStateBase
    {
        public override LevelInteractState stateId => LevelInteractState.Operational;
        public InteractStateOperational(LevelPlayRegionController regionCtrl) : base(regionCtrl)
        {

        }

        public event Action<LeanFinger> onTouchTap;
        public event Action<List<LeanFinger>> onTouchGesture;
        public event Action<LeanFinger> onTouchUp;

        /// <summary>
        /// 交互ui，摇杆和按钮
        /// </summary>
        private UILevelInput uiLevelInput { set; get; }
        /// <summary>
        /// 是否可移动
        /// </summary>
        public bool isMovable => this.active && !_isShowStandBubble;
        /// <summary>
        /// 是否正在移动中
        /// </summary>
        public bool isMoving { private set; get; }

        /// <summary>
        /// 跳跃功能
        /// </summary>
        public InteractJump interactJump { protected set; get; }

        /// <summary>
        /// 当前检测的交互状态
        /// </summary>
        private float _checkTime = 0;
        /// <summary>
        /// 主角
        /// </summary>
        private LevelCharacterEntity _mainCharacter;
        /// <summary>
        /// 上一次同步给逻辑层的主角位置
        /// </summary>
        private Vector3 _lastSyncPos;

        /// <summary>
        /// 移动同步服务器时间
        /// </summary>
        private float _syncMoveElapsedTime;
        /// <summary>
        /// 正在和主角交互的实体id
        /// </summary>
        private int interactEntityId;
        /// <summary>
        /// 正在进行不能移动的对话（气泡对话）
        /// </summary>
        private bool _isShowStandBubble;

        /// <summary>
        /// 主角交互类型
        /// </summary>
        private byte interactEntityState
        {
            get
            {
                return _mainCharacter == null ? (byte)0 : _mainCharacter.InteractTypeWithEntity;
            }
            set
            {
                _mainCharacter.InteractTypeWithEntity = value;
            }
        }

        public override void OnInit()
        {
            //初始化lean touch
            LeanTouch.OnGesture += OnTouchGesture;
            LeanTouch.OnFingerTap += OnTouchTap;
            LeanTouch.OnFingerUp += OnTouchUp;

            this.interactJump = new InteractJump(this);

            MsgDispatcher.AddListener(MsgEventType.EntityEnterStateBubble, EnterStateBubble);
            MsgDispatcher.AddListener(MsgEventType.EntityExitStateBubble, ExitStateBubble);
            MsgDispatcher.AddListener<EntityParamLedgeData, LevelPlayBaseEntity>(MsgEventType.Level_AddJumpLedge, AddJumpLedgeData);
            MsgDispatcher.AddListener<EntityParamLedgeData, LevelPlayBaseEntity>(MsgEventType.Level_RemoveJumpLedge, RemoveJumpLedgeData);
        }

        public override void OnEnter(LevelInteractState prevStateId)
        {
            _mainCharacter = regionCtrl.entityCtrl.GetMainCharacter();
        }

        public override void OnExit()
        {
            StopCharacterMove(true);
            _mainCharacter = null;
            _syncMoveElapsedTime = 0;
        }

        public override void Dispose()
        {
            LeanTouch.OnGesture -= OnTouchGesture;
            LeanTouch.OnFingerTap -= OnTouchTap;
            LeanTouch.OnFingerUp -= OnTouchUp;
            onTouchGesture = null;
            onTouchTap = null;
            onTouchUp = null;

            MsgDispatcher.RemoveListener(MsgEventType.EntityEnterStateBubble, EnterStateBubble);
            MsgDispatcher.RemoveListener(MsgEventType.EntityExitStateBubble, ExitStateBubble);
            MsgDispatcher.RemoveListener<EntityParamLedgeData, LevelPlayBaseEntity>(MsgEventType.Level_AddJumpLedge, AddJumpLedgeData);
            MsgDispatcher.RemoveListener<EntityParamLedgeData, LevelPlayBaseEntity>(MsgEventType.Level_RemoveJumpLedge, RemoveJumpLedgeData);
        }

        public override bool IsNextStateValid(LevelInteractState nextId)
        {
            return true;
        }

        public void AddJoystickListener()
        {
            //移动摇杆
            uiLevelInput = this.regionCtrl?.uilevelInput;
            if (uiLevelInput != null)
            {
                uiLevelInput.Show();
                uiLevelInput.AddJoystickListener(OnJoystickMove, OnJoystickUp);
                uiLevelInput.onClickInteract += OnClickInteract;
            }
        }

        protected void AddJumpLedgeData(EntityParamLedgeData ledgeData, LevelPlayBaseEntity entity)
        {
            this.interactJump.AddFromLedgeData(ledgeData, entity);
        }

        protected void RemoveJumpLedgeData(EntityParamLedgeData ledgeData, LevelPlayBaseEntity entity)
        {
            this.interactJump.RemoveFromLedgeData(ledgeData, entity);
        }

        protected void EnterStateBubble()
        {
            _isShowStandBubble = true;
            if (this.active)
            {
                _mainCharacter.StopMoveAnimImmediately();
            }
        }

        protected void ExitStateBubble()
        {
            _isShowStandBubble = false;
        }

        public override void OnUpdate(float deltaTime)
        {
            if (!this.active)
            {
                return;
            }
            _checkTime += deltaTime;
            if (_checkTime >= ViewEntityConst.CheckInteractInterval)
            {
                _checkTime = 0;
                CheckEntityInteract();
            }

            //设置交互按钮
            if (interactEntityState == 0)
            {
                this.uiLevelInput?.SetInteractState(1);
            }
            else
            {
                this.uiLevelInput?.SetInteractState((int)interactEntityState);
            }

            interactJump?.Update(deltaTime);

            if (isMoving)
            {
                _syncMoveElapsedTime += deltaTime;
                if (_syncMoveElapsedTime >= LevelDataConsts.MoveSyncInterval)
                {
                    SyncPosToServer();
                }
            }
        }

        public void OnJoystickMove(JoystickData joystickData)
        {
            if (!isMovable)
            {
                return;
            }
            var animCom = _mainCharacter.GetAnimationComponent();
            animCom.SetJoyStickPower(joystickData.power);
            _mainCharacter.GetMoveComponent().MoveStep(joystickData.angle, joystickData.power);

            bool isStartMove = false;
            if (!isMoving)
            {
                isStartMove = true;
                MsgDispatcher.Broadcast(MsgEventType.EntityStartMove, joystickData.power);
            }
            animCom.SetStartMove(isStartMove);
            isMoving = true;
        }

        public void OnJoystickUp()
        {
            if (!isMovable)
            {
                return;
            }
            var animCom = _mainCharacter.GetAnimationComponent();
            animCom.SetJoyStickPower(0);
            StopCharacterMove();
        }

        public void StopCharacterMove(bool stopAnimationNow = false)
        {
            _mainCharacter.GetMoveComponent().StopMove(stopAnimationNow);
            SyncPosToServer();
            isMoving = false;
        }

        private void SyncPosToServer()
        {
            var character = _mainCharacter;
            var dynEntity = character.dynEntity;
            if (!dynEntity.isInMainPhasing)
            {
                return;
            }

            var logicPosition = new Vector3(dynEntity.x, dynEntity.y, dynEntity.z);
            if (logicPosition.x == _lastSyncPos.x && logicPosition.z == _lastSyncPos.z)
            {
                return;
            }
            _lastSyncPos = logicPosition;
            if (LevelPlayModule.Instance.inLevelPlay && regionCtrl.levelPlayCtrl.isLevelPlayStarted)
            {
                CLevelLogicModule.NetCore.CS_Move(dynEntity.x, dynEntity.y, dynEntity.z);
            }
            _syncMoveElapsedTime = 0;
        }

        /// <summary>
        /// 点击交互按钮的逻辑
        /// </summary>
        /// <returns></returns>
        private async UniTaskVoid ClickInteractLogic()
        {
            if (!this.active)
            {
                if (interactEntityState == 0)
                {
                    this.fsm.BroadcastEvent(LevelInteractEvent.ClickInteract);
                }
                return;
            }
            if (interactEntityState != 0)
            {
                var interactCfg = TableCenter.entityInteractType.Get((int)interactEntityState);
                if (regionCtrl.entityCtrl.entitys.TryGetValue(interactEntityId, out var otherEntity)
                    && interactCfg.IsHeroRotate)
                {
                    var moveComponent = _mainCharacter?.GetMoveComponent();
                    if (moveComponent != null)
                    {
                        await moveComponent.RotateWithAnimation(otherEntity.GetUnityVec3Pos());
                    }
                }
            }
            StopCharacterMove();
            ChangeState(LevelInteractState.InteractWithNPC);
        }

        public void OnClickInteract()
        {
            ClickInteractLogic().Forget();
        }

        public void OnTouchGesture(List<LeanFinger> fingers)
        {
            if (!this.active)
            {
                return;
            }
            onTouchGesture?.Invoke(fingers);
        }

        public void OnTouchTap(LeanFinger leanFinger)
        {
            if (!this.active)
            {
                return;
            }
            onTouchTap?.Invoke(leanFinger);
        }

        public void OnTouchUp(LeanFinger leanFinger)
        {
            if (!this.active)
            {
                return;
            }
            onTouchUp?.Invoke(leanFinger);
        }

        /// <summary>
        /// 定时检测周围实体交互信息
        /// </summary>
        public void CheckEntityInteract()
        {
            var character = _mainCharacter;
            if (character == null)
            {
                return;
            }
            var characterPos = character.GetUnityVec3Pos();

            //使用四叉树查询主角(LevelDataConsts.QuadTreeSearchHalfSize)范围内的实体
            var qtEntitys = ListPool<LevelPlayBaseEntity>.Get();
            character.GetTransformPosXZ(out var x, out var z);
            var area = GameMathUtil.GetRectRangeV2(x, z, LevelDataConsts.QuadTreeSearchHalfSize);
            regionCtrl.entityCtrl.QTRetrieveObjects(qtEntitys, area);

            // 当前交互类型
            var oldInteractEntityState = interactEntityState;
            var oldInteractEntityId = interactEntityId;
            interactEntityState = 0;

            LevelPlayBaseEntity interactEntity = null;
            float minPriority = float.MaxValue;
            foreach (var entity in qtEntitys)
            {
                var entityInteractType = entity.interactType;
                if (entityInteractType == 0)
                {
                    continue;
                }

                var characterForward = character.transform.forward;
                characterForward.y = 0;
                //计算优先级
                var priority = GameScenePlayUtil.GetEntityInteractPriority(character.cfgEntity.InteractExtendedRange,
                   characterPos, characterForward, entityInteractType, entity.GetUnityVec3Pos(),
                   entity.GetDynLevelEntity().levelEntityConfig.obstacle);

                if (priority < minPriority)
                {
                    minPriority = priority;
                    interactEntity = entity;
                }
            }

            bool changed = false;
            //当前有可以交互的实体
            if (interactEntity != null)
            {
                interactEntityState = interactEntity.interactType;
                interactEntityId = interactEntity.id;
                if (interactEntityState != oldInteractEntityState || interactEntityId != oldInteractEntityId)
                {
                    changed = true;
                }
            }
            else if (oldInteractEntityState != 0)
            {
                changed = true;
            }

            if (changed)
            {
                regionCtrl.entityCtrl.toInteractEntity = interactEntity;
                // 更改之后,需要刷新头顶指示器
                RefreshInteactHeadIndicator(interactEntity);
            }

            ListPool<LevelPlayBaseEntity>.Put(qtEntitys);
        }


        /// <summary>
        /// 刷新头顶指示器
        /// </summary>
        /// <param name="interactEntity"></param>
        private void RefreshInteactHeadIndicator(LevelPlayBaseEntity interactEntity)
        {
            var entityCtrl = regionCtrl.entityCtrl;
            var realityEntity = interactEntity as LevelPlayRealityEntity;
            if (interactEntityState == 0 || realityEntity == null)
            {
                entityCtrl.SetHeadIndicatorOn(false);
                return;
            }

            var dynEntity = interactEntity.GetDynLevelEntity();
            if (dynEntity == null || !dynEntity.InteractiveIcon)
            {
                entityCtrl.SetHeadIndicatorOn(false);
                return;
            }

            // 显示头顶指示器
            entityCtrl.SetHeadIndicatorOn(true, realityEntity);
        }
    }
}
